package com.itrip.biz.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itrip.beans.pojo.*;
import com.itrip.beans.vo.*;
import com.itrip.biz.service.*;
import com.itrip.dao.HotelOrderMapper;
import com.itrip.dao.HotelRoomMapper;
import com.itrip.utils.dto.Dto;
import com.itrip.utils.util.DateUtil;
import com.itrip.utils.util.EmptyUtils;
import com.itrip.utils.util.*;
import com.itrip.utils.vo.DtoUtil;
import io.swagger.annotations.ApiParam;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/biz/api/hotelorder")
public class OrderFormController {

    @Autowired
    HotelOrderService hotelOrderService;
    @Autowired
    private HotelService hotelService;
    @Autowired
    private HotelRoomService hotelRoomService;
    @Autowired
    private HotelTempStoreService hotelTempStoreService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private OrderLinkUserService orderLinkUserService;

    @PostMapping("/getpersonalorderlist")
    public Dto<HotelOrder> getOrderForm(@RequestBody T orderS, HttpServletRequest request){
        PageVo pageVo= hotelOrderService.getOrderInfo(orderS,request);
        return DtoUtil.returnSuccess("",pageVo);
    }

    @GetMapping("/getpersonalorderinfo/{id}")
    public Dto getOrderInfo(@PathVariable("id") int id){
        OrderInfoVo orderInfoVo = hotelOrderService.getOrderInfoDetails(id);
        return DtoUtil.returnSuccess("",orderInfoVo);
    }

    @GetMapping("/getpersonalorderroominfo/{orderId}")
    public Dto getPersonalOrderRoomInfo(@PathVariable String orderId) {
        try {
            PersonalOrderRoomVO vo=hotelOrderService.getItripHotelOrderRoomInfoById(Long.valueOf(orderId));
            return DtoUtil.returnSuccess("获取个人订单房型信息成功",vo);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("获取个人订单房型信息错误");
        }
    }

    //生成订单前,获取预订信息
    @PostMapping("/getpreorderinfo")
    public Dto<RoomStoreVO> getPreOrderInfo(@RequestBody ValidateRoomStoreVO validateRoomStoreVO) {
        Hotel hotel = null;
        HotelRoom room = null;
        RoomStoreVO roomStoreVO = null;
        try {
            if (EmptyUtils.isEmpty(validateRoomStoreVO.getHotelId())) {
                return DtoUtil.returnFail("hotelId不能为空");
            } else if (EmptyUtils.isEmpty(validateRoomStoreVO.getRoomId())) {
                return DtoUtil.returnFail("roomId不能为空");
            } else {
                roomStoreVO = new RoomStoreVO();
                hotel = hotelService.getById(validateRoomStoreVO.getHotelId());
                room = hotelRoomService.getById(validateRoomStoreVO.getRoomId());
                Map param = new HashMap();
                param.put("startTime", validateRoomStoreVO.getCheckInDate());
                param.put("endTime", validateRoomStoreVO.getCheckOutDate());
                param.put("roomId", validateRoomStoreVO.getRoomId());
                param.put("hotelId", validateRoomStoreVO.getHotelId());
                roomStoreVO.setCheckInDate(validateRoomStoreVO.getCheckInDate());
                roomStoreVO.setCheckOutDate(validateRoomStoreVO.getCheckOutDate());
                roomStoreVO.setHotelName(hotel.getHotelName());
                roomStoreVO.setRoomId(room.getId());
                roomStoreVO.setPrice(room.getRoomPrice());
                roomStoreVO.setHotelId(validateRoomStoreVO.getHotelId());
                List<StoreVO> storeVOList = hotelTempStoreService.queryRoomStore(param);
                roomStoreVO.setCount(1);
                if (EmptyUtils.isNotEmpty(storeVOList)) {
                    roomStoreVO.setStore(storeVOList.get(0).getStore());
                } else {
                    return DtoUtil.returnFail("暂时无房");
                }
                return DtoUtil.returnSuccess("获取成功", roomStoreVO);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("系统异常");
        }
    }

    //生成订单
    @PostMapping("/addhotelorder")
    public Dto<Object> addHotelOrder(@RequestBody ItripAddHotelOrderVO itripAddHotelOrderVO, javax.servlet.http.HttpServletRequest request) {
        String tokenString = request.getHeader("token");
        String userId =stringRedisTemplate.opsForValue().get(tokenString);
        Map<String, Object> validateStoreMap = new HashMap<String, Object>();
        validateStoreMap.put("startTime", itripAddHotelOrderVO.getCheckInDate());
        validateStoreMap.put("endTime", itripAddHotelOrderVO.getCheckOutDate());
        validateStoreMap.put("hotelId", itripAddHotelOrderVO.getHotelId());
        validateStoreMap.put("roomId", itripAddHotelOrderVO.getRoomId());
        validateStoreMap.put("count", itripAddHotelOrderVO.getCount());
        List<UserLinkUser> linkUserList = itripAddHotelOrderVO.getLinkUser();
        if(EmptyUtils.isEmpty(userId)){
            return DtoUtil.returnFail("token失效，请重登录");
        }
        try {
            //判断库存是否充足
            Boolean flag = hotelTempStoreService.validateRoomStore(validateStoreMap);
            if (flag && null != itripAddHotelOrderVO) {
                //计算订单的预定天数
                Integer days = DateUtil.getBetweenDates(
                        itripAddHotelOrderVO.getCheckInDate(), itripAddHotelOrderVO.getCheckOutDate()
                ).size()-1;
                if(days<=0){
                    return DtoUtil.returnFail("退房日期必须大于入住日期");
                }
                HotelOrder itripHotelOrder = new HotelOrder();
                itripHotelOrder.setId(itripAddHotelOrderVO.getId());
                itripHotelOrder.setUserId(Long.valueOf(userId));
                itripHotelOrder.setOrderType(itripAddHotelOrderVO.getOrderType());
                itripHotelOrder.setHotelId(itripAddHotelOrderVO.getHotelId());
                itripHotelOrder.setHotelName(itripAddHotelOrderVO.getHotelName());
                itripHotelOrder.setRoomId(itripAddHotelOrderVO.getRoomId());
                itripHotelOrder.setCount(itripAddHotelOrderVO.getCount());
                itripHotelOrder.setCheckInDate(itripAddHotelOrderVO.getCheckInDate());
                itripHotelOrder.setCheckOutDate(itripAddHotelOrderVO.getCheckOutDate());
                itripHotelOrder.setNoticePhone(itripAddHotelOrderVO.getNoticePhone());
                itripHotelOrder.setNoticeEmail(itripAddHotelOrderVO.getNoticeEmail());
                itripHotelOrder.setSpecialRequirement(itripAddHotelOrderVO.getSpecialRequirement());
                itripHotelOrder.setIsNeedInvoice(itripAddHotelOrderVO.getIsNeedInvoice());
                itripHotelOrder.setInvoiceHead(itripAddHotelOrderVO.getInvoiceHead());
                itripHotelOrder.setInvoiceType(itripAddHotelOrderVO.getInvoiceType());
                itripHotelOrder.setCreatedBy(Long.valueOf(userId));
                StringBuilder linkUserName = new StringBuilder();
                int size = linkUserList.size();
                for (int i = 0; i < size; i++) {
                    if (i != size - 1) {
                        linkUserName.append(linkUserList.get(i).getLinkUserName() + ",");
                    } else {
                        linkUserName.append(linkUserList.get(i).getLinkUserName());
                    }
                }
                itripHotelOrder.setLinkUserName(linkUserName.toString());
                itripHotelOrder.setBookingDays(days);

                    itripHotelOrder.setBookType(0);
                //支付之前生成的订单的初始状态为未支付
                itripHotelOrder.setOrderStatus(0);
                try {
                    //生成订单号：机器码 +日期+（MD5）（商品IDs+毫秒数+1000000的随机数）
                    StringBuilder md5String = new StringBuilder();
                    md5String.append(itripHotelOrder.getHotelId());
                    md5String.append(itripHotelOrder.getRoomId());
                    md5String.append(System.currentTimeMillis());
                    md5String.append(Math.random() * 1000000);
                    String md5 = MD5.getMd5(md5String.toString(), 6);

                    //生成订单编号
                    StringBuilder orderNo = new StringBuilder();
                    orderNo.append("D1000001");
                    orderNo.append(DateUtil.format(new Date(), "yyyyMMddHHmmss"));
                    orderNo.append(md5);
                    itripHotelOrder.setOrderNo(orderNo.toString());
                    //计算订单的总金额
                    itripHotelOrder.setPayAmount(hotelOrderService.getOrderPayAmount(days * itripAddHotelOrderVO.getCount(), itripAddHotelOrderVO.getRoomId()));

                    Map<String, String> map = hotelOrderService.itriptxAddItripHotelOrder(itripHotelOrder, linkUserList);
                    DtoUtil.returnSuccess();
                    return DtoUtil.returnSuccess("生成订单成功", map);
                } catch (Exception e) {
                    e.printStackTrace();
                    return DtoUtil.returnFail("生成订单失败");
                }
            } else if (flag && null == itripAddHotelOrderVO) {
                return DtoUtil.returnFail("不能提交空，请填写订单信息");
            } else {
                return DtoUtil.returnFail("库存不足");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("系统异常");
        }
    }
    /***
     * 10分钟执行一次  判断订单两小时之内是否支付  否则改变订单状态为 已取消
     */
    @Scheduled(cron = "0/600 * * * * ? ")
    public void flushCancelOrderStatus() {
        System.out.println("ajdiadl");
        try {
            boolean flag = hotelOrderService.flushOrderStatus(1);

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("定时失败");
        }
    }

    /***
     * 两小时执行一次  判断订单退房时间是否过期  则修改订单状态 （以消费）
     */
    @Scheduled(cron = "*/7200 * * * * ?")
    public void flushOrderStatus() {
        try {
            boolean flag = hotelOrderService.flushOrderStatus(2);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("定时失败");

        }
    }

    //根据订单ID获取订单信息
    @GetMapping("/queryOrderById/{orderId}")
    public Dto queryOrderById(@PathVariable Long orderId) {
        ItripModifyHotelOrderVO orderVO=new ItripModifyHotelOrderVO();
        HotelOrder order=hotelOrderService.getById(orderId);
        BeanUtils.copyProperties(order,orderVO);
        QueryWrapper qw=new QueryWrapper();
        qw.eq("order_id",orderId);
        List<OrderLinkUser> linkUsers=orderLinkUserService.list(qw);
        orderVO.setOrderLinkUserList(linkUsers);
        return DtoUtil.returnSuccess("获取订单成功", orderVO);
    }
}
